package com.dragon.modules.yuegou.client.wechat_mini.service;

import com.dragon.modules.yuegou.client.wechat_mini.model.Category;
import com.dragon.modules.yuegou.client.wechat_mini.model.Keyword;
import com.dragon.modules.yuegou.client.wechat_mini.model.PriTemplate;
import com.dragon.modules.yuegou.client.wechat_mini.model.SubscribeMessage;
import com.dragon.modules.yuegou.client.wechat_mini.model.Template;
import com.dragon.modules.yuegou.client.wechat_mini.model.TemplateTitle;
import com.dragon.modules.yuegou.client.wechat_mini.request.SubscribeMessageRequest;
import com.dragon.modules.yuegou.client.wechat_mini.request.TemplateAddRequest;
import com.dragon.modules.yuegou.client.wechat_mini.response.TemplateTitleResponse;

import javax.annotation.Nullable;
import java.util.List;
import java.util.stream.Stream;

/**
 * 订阅消息服务
 * 
 * @author liuwu
 *
 */
public interface SubscribeMessageService {

	/**
	 * 配置模板<br>
	 * 此方法不会进行接口调用，它是<code>send(message)</code>的前置条件。建议初始化的时候进行配置
	 * 
	 * @param templateConfig 添加模板请求
	 */
	void configTemplate(List<TemplateAddRequest> templateConfig);

	/**
	 * 获取配置的模板<br>
	 * 要求先调用configTemplate(request)方法进行模板配置，否则一定会返回null。
	 * 
	 * @param tid 公用模板ID
	 * @return 模板详细信息
	 */
	@Nullable
	Template getConfiguredTemplate(Integer tid);

	/**
	 * 获取所有配置的模板<br>
	 * 要求先调用configTemplate(request)方法进行模板配置，否则一定会返回空列表。
	 * 
	 * @return 模板列表
	 */
	List<Template> getAllConfiguredTemplate();

	/**
	 * 发送订阅消息<br>
	 * 此方法使用的模板ID是公用模板ID，要求先调用configTemplate(request)方法进行模板配置。
	 * 
	 * @param message 订阅消息
	 * @return true表示消息发送成功， false表示由于用户未同意授权或拒收消息导致的发送失败
	 */
	boolean send(SubscribeMessage message);

	/**
	 * 发送订阅消息
	 * 
	 * @param request 订阅消息请求
	 * @return true表示消息发送成功， false表示由于用户未同意授权或拒收消息导致的发送失败
	 */
	boolean sendRawMessage(SubscribeMessageRequest request);

	/**
	 * 添加模板
	 * 
	 * @param request 模板添加请求
	 * @return 添加至帐号下的模板id，发送小程序订阅消息时所需
	 */
	String addTemplate(TemplateAddRequest request);

	/**
	 * 删除模板
	 * 
	 * @param priTmplId 添加至帐号下的模板id，发送小程序订阅消息时所需
	 */
	void deleteTemplate(String priTmplId);

	/**
	 * 获取小程序账号的类目
	 * 
	 * @return 类目列表
	 */
	List<Category> getCategory();

	/**
	 * 获取模板标题下的关键词列表
	 * 
	 * @param tid 公用模板ID
	 * @return 关键词列表
	 */
	List<Keyword> getPubTemplateKeyWordsById(Integer tid);

	/**
	 * 分页查询帐号所属类目下的公共模板标题
	 * 
	 * @param categoryIds 类目ID列表
	 * @param start       起始下标，从0开始
	 * @param limit       每页限制条数，最大30
	 * @return 公用模板标题数据流
	 */
	TemplateTitleResponse getPubTemplateTitleList(List<Integer> categoryIds, int start, int limit);

	/**
	 * 获取帐号所属类目下的公共模板标题
	 * 
	 * @param categoryIds 类目ID列表
	 * @return 公用模板标题数据流
	 */
	Stream<TemplateTitle> getPubTemplateTitleStream(List<Integer> categoryIds);

	/**
	 * 获取当前小程序类目下的所有公共模板标题
	 * 
	 * @return 公用模板标题数据流
	 */
	Stream<TemplateTitle> getMyPubTemplateTitleStream();

	/**
	 * 获取当前帐号下的个人模板列表
	 * 
	 * @return 当前帐号下的个人模板列表
	 */
	List<PriTemplate> getTemplateList();

	/**
	 * 同步模板至小程序账号<br>
	 * 此方法能保证幂等性，添加模板后再次调用不会重复添加
	 * 
	 * @param request 同步请求，注意：一个小程序号最多能够添加25个模板
	 * @return 同步后的模板列表
	 */
	List<Template> syncTemplate(List<TemplateAddRequest> request);
}
